import type { Recordable, UserInfo } from '@vben/types';

import { ref } from 'vue';
import { useRouter } from 'vue-router';

import { LOGIN_PATH } from '@vben/constants';
import { preferences } from '@vben/preferences';
import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores';

import { notification } from 'ant-design-vue';
import { defineStore } from 'pinia';

import { getCurrentUserPermissionsApi, getUserInfoApi, loginApi, logoutApi } from '#/api';
import { $t } from '#/locales';
import { debugToken, parseJwtToken } from '#/utils/token';

export const useAuthStore = defineStore('auth', () => {
  const accessStore = useAccessStore();
  const userStore = useUserStore();
  const router = useRouter();

  const loginLoading = ref(false);

  /**
   * 异步处理登录操作
   * Asynchronously handle the login process
   * @param params 登录表单数据
   */
  async function authLogin(
    params: Recordable<any>,
    onSuccess?: () => Promise<void> | void,
  ) {
    // 异步处理用户登录操作并获取 accessToken
    let userInfo: null | UserInfo = null;
    try {
      loginLoading.value = true;
      const loginResult = await loginApi(params);

      // 如果成功获取到 accessToken
      if (loginResult.accessToken) {
        // 存储 accessToken 和 refreshToken
        accessStore.setAccessToken(loginResult.accessToken);
        accessStore.setRefreshToken(loginResult.refreshToken);

        // 🔍 调试：验证 token 是否成功保存
        if (import.meta.env.DEV) {
          console.log('🔐 [登录] Token 保存状态:', {
            '保存的 token 长度': loginResult.accessToken.length,
            '从 store 读取的 token 长度': accessStore.accessToken?.length || 0,
            'token 是否一致': loginResult.accessToken === accessStore.accessToken,
            '保存的 token 前20字符': loginResult.accessToken.substring(0, 20),
            '从 store 读取的 token 前20字符': accessStore.accessToken?.substring(0, 20) || 'null',
          });
        }

        // 从 Token 中解析用户基本信息
        const tokenPayload = parseJwtToken(loginResult.accessToken);

        // 调试：打印 Token 信息
        if (import.meta.env.DEV) {
          debugToken(loginResult.accessToken);
        }

        // 从 Token 中构建用户信息
        userInfo = {
          userId: tokenPayload?.userId || loginResult.username, // 优先使用 Token 中的 userId
          username: tokenPayload?.username || loginResult.username,
          realName: tokenPayload?.username || loginResult.username,
          roles: [], // 角色信息将从 getCurrentUserPermissions 接口获取
          avatar: '', // 默认头像
          desc: '',
          homePath: preferences.app.defaultHomePath,
          token: loginResult.accessToken,
        } as UserInfo;

        // 存储用户信息
        userStore.setUserInfo(userInfo);

        console.log('✅ 登录成功，用户信息已保存:', {
          userId: userInfo.userId,
          username: userInfo.username,
        });

        // 注意：权限信息将在路由守卫中通过 fetchMenuListAsync 加载
        // 不在登录时加载，避免重复请求

        // 可选：如果后端提供了 /user/info 接口且返回更详细的信息（如头像、描述等），可以取消下面的注释
        // try {
        //   const detailedUserInfo = await fetchUserInfo();
        //   if (detailedUserInfo) {
        //     userInfo = detailedUserInfo;
        //     userStore.setUserInfo(detailedUserInfo);
        //   }
        // } catch (error) {
        //   console.warn('Failed to fetch detailed user info:', error);
        // }

        if (accessStore.loginExpired) {
          accessStore.setLoginExpired(false);
        } else {
          if (onSuccess) {
            await onSuccess?.();
          } else if (userInfo) {
            const targetPath = userInfo.homePath || preferences.app.defaultHomePath;
            console.log('🚀 登录后跳转到:', targetPath);
            await router.push(targetPath);
          }
        }

        if (userInfo?.realName) {
          notification.success({
            description: `${$t('authentication.loginSuccessDesc')}:${userInfo?.realName}`,
            duration: 3,
            message: $t('authentication.loginSuccess'),
          });
        }
      }
    } catch (error: any) {
      // 捕获登录错误并显示错误消息
      // 错误对象可能有多种情况：
      // 1. 标准 Error 对象：error.respCode 和 error.respMsg 已设置
      // 2. 标准 Error 对象：error.response.data 包含响应数据
      // 3. 直接是响应数据对象：error 本身就是 { respCode, respMsg, datas }

      const responseData = error?.response?.data || error;

      // 获取错误码和错误消息（优先使用 error 对象上的属性）
      const respCode = error?.respCode || responseData?.respCode || 'ERROR';
      const respMsg =
        error?.respMsg || // 优先使用 error.respMsg（在 request.ts 中设置）
        responseData?.respMsg ||
        responseData?.message ||
        responseData?.msg ||
        error?.message ||
        '登录失败';

      // 显示错误通知 - 直接显示后端返回的原始信息
      notification.error({
        description: `[${respCode}] ${respMsg}`,
        duration: 5,
        message: '登录失败',
      });

      // 重新抛出错误，让调用者知道登录失败
      throw error;
    } finally {
      loginLoading.value = false;
    }

    return {
      userInfo,
    };
  }

  async function logout(redirect: boolean = true) {
    try {
      await logoutApi();
    } catch {
      // 不做任何处理
    }

    // 先清除 token，防止路由守卫重新触发权限检查
    accessStore.setAccessToken(null);
    accessStore.setRefreshToken(null);

    // 清除所有状态
    resetAllStores();
    accessStore.setLoginExpired(false);

    // 回登录页带上当前路由地址
    await router.replace({
      path: LOGIN_PATH,
      query: redirect
        ? {
            redirect: encodeURIComponent(router.currentRoute.value.fullPath),
          }
        : {},
    });
  }

  async function fetchUserInfo() {
    let userInfo: null | UserInfo = null;
    userInfo = await getUserInfoApi();
    // 如果 getUserInfoApi 返回 null（接口不存在），使用已存储的用户信息
    if (!userInfo && userStore.userInfo) {
      // 从 BasicUserInfo 转换为 UserInfo
      userInfo = {
        ...userStore.userInfo,
        desc: '',
        homePath: preferences.app.defaultHomePath,
        token: accessStore.accessToken || '',
      } as UserInfo;
    } else if (userInfo) {
      userStore.setUserInfo(userInfo);
    }
    return userInfo;
  }

  function $reset() {
    loginLoading.value = false;
  }

  return {
    $reset,
    authLogin,
    fetchUserInfo,
    loginLoading,
    logout,
  };
});
